package week3;
import jsjf.QueueADT;
import jsjf.exceptions.*;

// 表示一个队列的数组实现，当队列到达数组末尾时，队列的前后索引返回到0
public class CircularArrayQueue<T> implements QueueADT<T>
{
    private final static int DEFAULT_CAPACITY = 100;
    private int front, rear, count;
    private T[] queue;

    // 创建特定容量的数组
    public CircularArrayQueue (int initialCapacity)
    {
        front = rear = count = 0;
        queue = (T[]) (new Object[initialCapacity]);
    }

    // 创建默认容量的数组
    public CircularArrayQueue()
    {
        this(DEFAULT_CAPACITY);
    }

    // 添加元素
    public void enqueue(T element)
    {
        if (size() == queue.length)
            expandCapacity();

        queue[rear] = element;
        rear = (rear+1) % queue.length;

        count++;
    }

    // 创建一个新数组，以两倍于旧数组的容量存储此队列的内容
    private void expandCapacity()
    {
        T[] larger = (T[]) (new Object[queue.length *2]);

        for (int scan = 0; scan < count; scan++)
        {
            larger[scan] = queue[front];
            front = (front + 1) % queue.length;
        }

        front = 0;
        rear = count;
        queue = larger;
    }

    // 删除队列首端的元素并返回
    public T dequeue() throws EmptyCollectionException
    {
        if (isEmpty())
            throw new EmptyCollectionException("queue");

        T result = queue[front];
        queue[front] = null;
        front = (front+1) % queue.length;

        count--;

        return result;
    }


    public T first() throws EmptyCollectionException
    {
        T result = queue[front];
        return result;
    }


    public boolean isEmpty()
    {
        return front == rear;
    }


    public int size() {
        return count;
    }


    public String toString() {
        String result = "";
        int temp = front;
        for (int i = 0; i < count; i++) {
            result += queue[temp] + " ";
            temp = (temp + 1) % queue.length;
        }
        return result;
    }
}